/**
 * 装饰器，对Get、Post等进一步封装
 */

import request from './request'
import { stringUtils } from '@gyk/gyk-utils'

export type ResponseData = {
  code: number,
  data: any,
  msg: string | null
  rows?: any,
  total?: number
  [x: string]: any
}

/**
 * 规定axios的请求参数配置
 */
export type RequestParams = {
  params?: any,
  data?: any,
  path?: any,
  then?: Function,
  catch?: Function,
  [x: string]: any
}

type decoratorConfig = {
  headers?: object,
  requestType: 'params' | 'data' | 'path' | 'all'
}

// Get请求装饰器
export const Get = (url: string, decoratorConfig: decoratorConfig = { requestType: 'params' }) => {
  const methodDecorator: MethodDecorator = (target: any, key, desc: PropertyDescriptor) => {
    let headers = {}
    if (decoratorConfig.headers) {
      headers = decoratorConfig.headers
    }
    let replaceUrl = url
    // 获取原来的方法
    const originMethod = desc.value
    // 修改原来的方法
    desc.value = async function (requestParams: RequestParams): Promise<ResponseData> {
      let params = decoratorConfig.requestType == 'params' ? requestParams : null
      let data = decoratorConfig.requestType == 'data' ? requestParams : null
      if (decoratorConfig.requestType == 'path') {
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams)
      }
      if (decoratorConfig.requestType == 'all') {
        params = requestParams.params
        data = requestParams.data
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams.path)
      }
      return await request({
        url: replaceUrl,
        method: 'get',
        headers,
        params: params,
        data: data,
      }).then(res => {
        return originMethod(res);
      })
    }
  }
  return methodDecorator
}

// Post请求装饰器
export const Post = (url: string, decoratorConfig: decoratorConfig = { requestType: 'params' }) => {
  const methodDecorator: MethodDecorator = (target: any, key, desc: PropertyDescriptor) => {
    let headers = {}
    if (decoratorConfig.headers) {
      headers = decoratorConfig.headers
    }

    let replaceUrl = url
    // 获取原来的方法
    const originMethod = desc.value
    // 修改原来的方法
    desc.value = async function (requestParams: RequestParams) {
      let params = decoratorConfig.requestType == 'params' ? requestParams : null
      let data = decoratorConfig.requestType == 'data' ? requestParams : null
      if (decoratorConfig.requestType == 'path') {
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams)
      }
      if (decoratorConfig.requestType == 'all') {
        params = requestParams.params
        data = requestParams.data
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams.path)
      }
      return request({
        url: replaceUrl,
        method: 'post',
        headers,
        params: params,
        data: data
      }).then(res => {
        return originMethod(res);
      })
    }
  }
  return methodDecorator
}

// delete请求装饰器
export const Delete = (url: string, decoratorConfig: decoratorConfig = { requestType: 'params' }) => {
  const methodDecorator: MethodDecorator = (target: any, key, desc: PropertyDescriptor) => {
    let headers = {}
    if (decoratorConfig.headers) {
      headers = decoratorConfig.headers
    }
    let replaceUrl = url
    // 获取原来的方法
    const originMethod = desc.value
    // 修改原来的方法
    desc.value = async function (requestParams: RequestParams) {
      let params = decoratorConfig.requestType == 'params' ? requestParams : null
      let data = decoratorConfig.requestType == 'data' ? requestParams : null
      if (decoratorConfig.requestType == 'path') {
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams)
      }
      if (decoratorConfig.requestType == 'all') {
        params = requestParams.params
        data = requestParams.data
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams.path)
      }
      return request({
        url: replaceUrl,
        headers,
        method: 'delete',
        params: params,
        data: data
      }).then(res => {
        return originMethod(res);
      })
    }
  }
  return methodDecorator
}


export const Put = (url: string, decoratorConfig: decoratorConfig = { requestType: 'params' }) => {
  const methodDecorator: MethodDecorator = (target: any, key, desc: PropertyDescriptor) => {
    let headers = {}
    if (decoratorConfig.headers) {
      headers = decoratorConfig.headers
    }
    let replaceUrl = url
    // 获取原来的方法
    const originMethod = desc.value
    // 修改原来的方法
    desc.value = async function (requestParams: RequestParams) {
      let params = decoratorConfig.requestType == 'params' ? requestParams : null
      let data = decoratorConfig.requestType == 'data' ? requestParams : null
      if (decoratorConfig.requestType == 'path') {
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams)
      }
      if (decoratorConfig.requestType == 'all') {
        params = requestParams.params
        data = requestParams.data
        replaceUrl = stringUtils.replaceUrlVariables(url, requestParams.path)
      }
      return request({
        url: replaceUrl,
        headers,
        method: 'put',
        params: params,
        data: data
      }).then(res => {
        return originMethod(res);
      })
    }
  }
  return methodDecorator
}